package frsf.cidisi.exercise.laberinto.situationCalculus;

import java.util.Hashtable;

import frsf.cidisi.exercise.laberinto.situationCalculus.util.Orientacion;
import frsf.cidisi.exercise.laberinto.situationCalculus.util.Par;
import frsf.cidisi.faia.agent.ActionFactory;
import frsf.cidisi.faia.agent.Perception;
import frsf.cidisi.faia.agent.situationcalculus.KnowledgeBase;
import frsf.cidisi.faia.agent.situationcalculus.SituationCalculusPerception;
import frsf.cidisi.faia.exceptions.PrologConnectorException;

public class EstadoAgente extends KnowledgeBase {
	
	private AgenteLaberintoPerception alp;

    public EstadoAgente() throws PrologConnectorException {
		super("laberinto.pl"); 
		alp = null;

    }
    
    @Override
    public void updateState(Perception p) {
        this.tell((SituationCalculusPerception) p);

        if(alp == null) {
        	alp = (AgenteLaberintoPerception) p;
        	this.initState();
        }
    }
    
	@Override
    public void initState() {
    	int x = alp.getposicion_x();
    	int y = alp.getposicion_y();
    	this.addKnowledge("posicion([" + x + "," + y + "],0)");
        this.addKnowledge("orientacion([0,1],0)");
    }
    
    @Override
    public ActionFactory getActionFactory() {
        return AgenteLaberintoActionFactory.getInstance();
    }
    
    @Override
    public String getBestActionPredicate() {
        return "mejorAccion";
    }
    
    @Override
    public String getExecutedActionPredicate() {
        return "accion";
    }
    
    @Override
    public String getSituationPredicate() {
        return "situationActual";
    }

    @Override
    public String toString() {
        String str = "";
        String query = "posicion([X,Y]," + this.getSituation() + ")";
        Hashtable[] result = this.query(query);
        str += "Posicion: (" + result[0].get("X").toString() + ", " + result[0].get("Y").toString() + ")";
        result = this.query("orientacion([X,Y]," + this.getSituation() + ")");
        Orientacion o = new Orientacion(new Par(new Integer(result[0].get("X").toString()),
        		new Integer(result[0].get("Y").toString())));
        str += "; Orientacion: " +  o.toString();
        if(this.prologConnector.queryHasSolution("poseeLlave(" + this.getSituation() + ")"))
        	str += "; PoseeLlave ";
        result = this.query("pared([X1,Y1],[X2,Y2])");
        str += "; Paredes: ";
        for(Hashtable h : result) {
        	str += "[" + h.get("X1").toString() + "," + h.get("Y1").toString() + "],";
        	str += "[" + h.get("X2").toString() + "," + h.get("Y2").toString() + "]; ";
        }
        return str;
    }
    
    public void halt() {
    	this.prologConnector.executeNonQuery("retractall(posicion(_,_)).");
    	this.prologConnector.executeNonQuery("retractall(orientacion(_,_)).");
    	this.prologConnector.executeNonQuery("retractall(poseeLlave(_)).");
    	this.prologConnector.executeNonQuery("retractall(accion(_,_)).");
    	this.prologConnector.executeNonQuery("retractall(visitado(_)).");
    	this.prologConnector.executeNonQuery("retractall(situacionActual(_)).");
    	this.prologConnector.executeNonQuery("retractall(pared(_,_)).");
    	this.prologConnector.executeNonQuery("retractall(llave(_)).");
    	this.prologConnector.executeNonQuery("retractall(puerta(_)).");
    	this.prologConnector.executeNonQuery("retractall(cerrojo(_)).");
    	this.prologConnector.executeNonQuery("retractall(percepcion(_,_,_,_,_,_)).");
    }
}
